9章 通信
この章で学ぶ内容は以下
区切られた文脈どうしの通信方法
集約の設計原則に起因する連携方法の制約に対処する方法
複数の区切られた文脈にまたがる業務プロセスの実現方法
takumines.iconここでいうモデル変換は腐敗防止層のこと。他の文脈の概念を自身の文脈に持ち込まないための境界を設けるための戦略 ただ、連携方法によって文脈を提供・利用する側のどっちで変換するのか変わってくる
モデルの変換
異なる区切られた文脈を開発するチームが分かれている場合の連携方法として、モデルの共有がある
モデルの一部を共通部分として抽出し、進化させていく
区切られた文脈同士を接続する部分を「契約」 として抽出して、共通のリポジトリ内で管理する
モデルの変換ロジックは基本的に以下の2パターンになる
状態なし(ステートレス)
モデル変換は通信中に即時実行される
状態あり(ステートフル)
DBを使った複雑な変換になる
状態なしのモデル変換
実現方法
即時で変換し、変換結果は永続化しない
プロキシの実装方法は、同期式と非同期式がある
同期式
区切られた文脈のコードベースに変換ロジックを用意し、即時に変換するのが一般的
code:php
// 腐敗防止層での同期変換
class OrderServiceAdapter
{
public function __construct(
private ExternalOrderAPI $externalApi,
private OrderTranslator $translator
) {}
// 同期的に取得・変換
public function getOrder(OrderId $id): Order
{
// 異なる文脈 op 外部APIを同期呼び出し
$externalOrder = $this->externalApi->fetchOrder($id->value());
// その場で変換
$order = $this->translator->toDomain($externalOrder);
// 即座に返す(変換結果は保持しない)
return $order;
}
}
// 変換装置
class OrderTranslator
{
public function toDmain(ExternalOrderDTO $dto): Oeder
{
return new Order(/////)
}
}
非同期式
実現方法
AWS SQSなどの非同期通信技術を使って、異なる文脈と通信する際に変換したモデルをメッセージとして送信する
利用シーン
マイクロサービス間の通信
イベント駆動アーキテクチャでのコンテキスト間連携
基本的にはメッセージを受信する側が受け取ったメッセージを自分たちの文脈で扱いやすいように変換する
共有サービスに゙関しては、公開された言葉(決まったフォーマット)でモデルを提供する必要があるため、モデルの変換して提供する https://scrapbox.io/files/693ad49f70830f7dd5162b73.png
状態ありのモデル変換
以下のようなケースで状態ありのモデル変換を行う
複数のデータを集めて一つにまとめたい場合
さまざまな発生元からのデータを統合して単一のモデルに変換したい場合
複数のデータを集めて一つにまとめたい場合
表現したいモデルを作る場合に、複数の外部サービスから取得したデータが必要なケース
例
以下を統合した顧客プロファイルを作りたい場合
基本情報は顧客マスタシステム
購買履歴はECシステム
サポート履歴はCRMシステム
モデルとしてデータを変換し、DBなどに保存しておくことで、不要な外部サービス呼び出しを減らすことができる
さまざまな発生元からのデータを統合して単一のモデルに変換したい場合
BFFのようなユーザーインターフェースが複数のサービスからのデータを集めて組み立てる必要があるケースなど code:plan_text
マイクロサービスA (顧客情報) ─┐
マイクロサービスB (注文情報) ─┤
マイクロサービスC (商品情報) ─┼→ BFF → フロントエンド最適化モデル
マイクロサービスD (レビュー) ─┤
外部API (配送情報) ─┘
BFF側で、自身のコンテキストで扱うモデルに変換し、DBなどに保存しておくことで、不要なサービス連携を削減できる
集約どうしの連携
集約が他のコンポーネントと連携するやり方として業務イベント(ドメインイベント)の発行(publish)がある 外部のコンポーネントは、必要に応じが業務イベントの購買(subscribe)を行う
takumines.iconここで言うコンポーネントはおそらく以下
マイクロサービス単位
境界づけされた文脈単位